package top.zywork.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.Rank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.zywork.annotation.SysLog;
import top.zywork.common.BeanUtils;
import top.zywork.common.BindingResultUtils;
import top.zywork.common.StringUtils;
import top.zywork.dto.PagerDTO;
import top.zywork.dto.RanksUserDTO;
import top.zywork.query.ActivityRanksQuery;
import top.zywork.query.GameInfoQuery;
import top.zywork.query.RanksUserQuery;
import top.zywork.security.SecurityUtils;
import top.zywork.service.*;
import top.zywork.vo.*;

import java.util.List;

/**
 * RanksUserController控制器类<br/>
 *
 * 创建于2020-05-13<br/>
 *
 * @author http://zywork.top 危锦辉
 * @version 1.0
 */
@RestController
@RequestMapping("/ranks-user")
@Slf4j
public class RanksUserController extends BaseController {

    private RanksUserService ranksUserService;

    private GameInfoService gameInfoService;

    private ActivityService activityService;

    private UserDetailService userDetailService;

    private ActivityRanksService activityRanksService;

    @PostMapping("admin/save")
    @SysLog(description = "后台保存RanksUserVO")
    public ResponseStatusVO save(@RequestBody @Validated RanksUserVO ranksUserVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        ranksUserService.save(BeanUtils.copy(ranksUserVO, RanksUserDTO.class));
        return ResponseStatusVO.ok("添加成功", null);
    }

    @PostMapping("admin/batch-save")
    @SysLog(description = "后台批量保存RanksUserVO")
    public ResponseStatusVO saveBatch(@RequestBody @Validated List<RanksUserVO> ranksUserVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        ranksUserService.saveBatch(BeanUtils.copyListObj(ranksUserVOList, RanksUserDTO.class));
        return ResponseStatusVO.ok("批量添加成功", null);
    }

    @GetMapping("admin/remove/{id}")
    @SysLog(description = "后台删除RanksUserVO")
    public ResponseStatusVO removeById(@PathVariable("id") Long id) {
        ranksUserService.removeById(id);
        return ResponseStatusVO.ok("删除成功", null);
    }

    @PostMapping("admin/batch-remove")
    @SysLog(description = "后台批量删除RanksUserVO")
    public ResponseStatusVO removeByIds(@RequestBody String[] ids) {
        ranksUserService.removeByIds(StringUtils.strArrayToLongArray(ids));
        return ResponseStatusVO.ok("批量删除成功", null);
    }

    @PostMapping("admin/update")
    @SysLog(description = "后台更新RanksUserVO")
    public ResponseStatusVO update(@RequestBody @Validated RanksUserVO ranksUserVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        int updateRows = ranksUserService.update(BeanUtils.copy(ranksUserVO, RanksUserDTO.class));
        if (updateRows == 1) {
            return ResponseStatusVO.ok("更新成功", null);
        } else {
            return ResponseStatusVO.dataError("数据版本号有问题，在此更新前数据已被更新", null);
        }
    }

    @PostMapping("admin/batch-update")
    @SysLog(description = "后台批量更新RanksUserVO")
    public ResponseStatusVO updateBatch(@RequestBody @Validated List<RanksUserVO> ranksUserVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        ranksUserService.updateBatch(BeanUtils.copyListObj(ranksUserVOList, RanksUserDTO.class));
        return ResponseStatusVO.ok("批量更新成功", null);
    }

    @PostMapping("admin/active")
    @SysLog(description = "后台激活或冻结RanksUserVO")
    public ResponseStatusVO active(@RequestBody RanksUserVO ranksUserVO) {
        ranksUserService.update(BeanUtils.copy(ranksUserVO, RanksUserDTO.class));
        return ResponseStatusVO.ok("激活或冻结成功", null);
    }

    @PostMapping("admin/batch-active")
    @SysLog(description = "后台批量激活或冻结RanksUserVO")
    public ResponseStatusVO activeBatch(@RequestBody @Validated List<RanksUserVO> ranksUserVOList) {
        ranksUserService.updateBatch(BeanUtils.copyListObj(ranksUserVOList, RanksUserDTO.class));
        return ResponseStatusVO.ok("批量激活或冻结成功", null);
    }

    @GetMapping("admin/one/{id}")
    public ResponseStatusVO getById(@PathVariable("id") Long id) {
        RanksUserVO ranksUserVO = new RanksUserVO();
        Object obj = ranksUserService.getById(id);
        if (obj != null) {
            ranksUserVO = BeanUtils.copy(obj, RanksUserVO.class);
        }
        return ResponseStatusVO.ok("查询成功", ranksUserVO);
    }

    @GetMapping("admin/all")
    public ResponseStatusVO listAll() {
        PagerDTO pagerDTO = ranksUserService.listAll();
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), RanksUserVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/all-cond")
    public ResponseStatusVO listAllByCondition(@RequestBody RanksUserQuery ranksUserQuery) {
        PagerDTO pagerDTO = ranksUserService.listAllByCondition(ranksUserQuery);
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), RanksUserVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/pager-cond")
    public ResponseStatusVO listPageByCondition(@RequestBody RanksUserQuery ranksUserQuery) {
        PagerDTO pagerDTO = ranksUserService.listPageByCondition(ranksUserQuery);
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), RanksUserVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    /**
     * 用户报名
     * @return
     */
    @PostMapping("user/sign-up")
    public ResponseStatusVO userSignUp(Long id, Long activityId) {
        Long userId = SecurityUtils.getJwtUser().getUserId();
        Object object = ranksUserService.getById(id);
        if (null == object) {
            return ResponseStatusVO.error("报名失败,队伍不存在", null);
        }
        RanksUserVO tempRanksUserVO = BeanUtils.copy(object, RanksUserVO.class);
        if (tempRanksUserVO.getUserId() != null) {
            return ResponseStatusVO.error("报名失败，该位置已有报名信息", null);
        }
        // 验证当前用户是否可以报名
        RanksUserVO validRanksUserVO = ranksUserService.validUserSignUp(userId);
        if (validRanksUserVO != null) {
            return ResponseStatusVO.error("报名失败，你有进行中的活动", null);
        }
        // 查询用户游戏信息
        GameInfoQuery gameInfoQuery = GameInfoQuery.builder().userId(userId).build();
        List<Object> tempGameInfoObjectList = gameInfoService.listAllByCondition(gameInfoQuery).getRows();
        if (tempGameInfoObjectList.isEmpty()) {
            return ResponseStatusVO.error("请先完善个人信息", null);
        }
        GameInfoVO gameInfoVO = BeanUtils.copy(tempGameInfoObjectList.get(0), GameInfoVO.class);
        ActivityVO activityVO = BeanUtils.copy(activityService.getById(activityId), ActivityVO.class);
        if (!activityVO.getRegional().equals(gameInfoVO.getRegional())) {
            return ResponseStatusVO.error("报名失败，此活动只有" + activityVO.getRegional() + "才能参加", null);
        }
        UserDetailVO userDetailVO = BeanUtils.copy(userDetailService.getById(userId), UserDetailVO.class);
        RanksUserVO ranksUserVO = RanksUserVO.builder().id(id).userId(userId).gameId(gameInfoVO.getGameId()).level(gameInfoVO.getLevel()).gender(userDetailVO.getGender()).build();
        int updateRows = ranksUserService.update(ranksUserVO);
        if (updateRows <= 0) {
            return ResponseStatusVO.error("报名失败", null);
        }
        // 报名成功，判断是否需要更新活动状态
        if (validActivity(activityId)) {
            ActivityVO updateActivityVO = ActivityVO.builder().id(activityId).status("待开始").build();
            activityService.update(updateActivityVO);
        }
        activityVO = BeanUtils.copy(activityService.getById(activityId), ActivityVO.class);
        return ResponseStatusVO.ok("报名成功", activityVO);
    }

    /**
     * 验证活动是否需要改变状态
     * @param activityId
     * @return
     */
    private boolean validActivity(Long activityId) {
        boolean flag = false;
        List<RanksUserVO> ranksUserVOList = ranksUserService.getByActivityId(activityId);
        for (RanksUserVO ranksUserVO : ranksUserVOList) {
            if (ranksUserVO.getUserId() == null) {
                // 还有未报名的，不需要改变状态
                flag = false;
                break;
            }
            flag = true;
        }
        return flag;
    }

    /**
     * 后台取消报名
     * @param id
     * @param activityRanksId
     * @return
     */
    @PostMapping("admin/cancel-sign-up")
    public ResponseStatusVO cancelSingUp(Long id, Long activityRanksId) {
        Object object = ranksUserService.getById(id);
        if (null == object) {
            return ResponseStatusVO.error("取消报名失败,队伍不存在", null);
        }
        RanksUserVO tempRanksUserVO = BeanUtils.copy(object, RanksUserVO.class);
        if (tempRanksUserVO.getUserId() == null) {
            return ResponseStatusVO.error("取消报名失败，该位置没有报名信息", null);
        }
        ActivityRanksVO activityRanksVO = BeanUtils.copy(activityRanksService.getById(activityRanksId), ActivityRanksVO.class);
        if (null == activityRanksVO) {
            return ResponseStatusVO.error("取消报名失败，队伍不存在", null);
        }
        Long activityId = activityRanksVO.getActivityId();
        int updateRows = ranksUserService.cancelSignUp(id);
        if (updateRows <= 0) {
            return ResponseStatusVO.error("取消报名失败", null);
        }
        ActivityVO updateActivityVO = ActivityVO.builder().id(activityId).status("报名中").build();
        activityService.update(updateActivityVO);
        ActivityVO activityVO = BeanUtils.copy(activityService.getById(activityId), ActivityVO.class);
        return ResponseStatusVO.ok("取消报名成功", activityVO);
    }

    /**
     * 用户取消报名
     * @return
     */
    @PostMapping("user/cancel-sign-up")
    public ResponseStatusVO userCancelSignUp(Long id, Long activityId) {
        Long userId = SecurityUtils.getJwtUser().getUserId();
        Object object = ranksUserService.getById(id);
        if (null == object) {
            return ResponseStatusVO.error("取消报名失败,队伍不存在", null);
        }
        RanksUserVO tempRanksUserVO = BeanUtils.copy(object, RanksUserVO.class);
        if (tempRanksUserVO.getUserId() == null) {
            return ResponseStatusVO.error("取消报名失败，该位置没有报名信息", null);
        }
        if (tempRanksUserVO.getUserId().longValue() != userId) {
            return ResponseStatusVO.error("取消报名失败，只能取消自己的报名信息", null);
        }
        // 验证当前用户是否可以报名
        RanksUserVO validRanksUserVO = ranksUserService.validUserSignUp(userId);
        if (validRanksUserVO == null) {
            return ResponseStatusVO.error("取消报名失败，你未参加过报名", null);
        }
        int updateRows = ranksUserService.cancelSignUp(id);
        if (updateRows <= 0) {
            return ResponseStatusVO.error("取消报名失败", null);
        }
        ActivityVO updateActivityVO = ActivityVO.builder().id(activityId).status("报名中").build();
        activityService.update(updateActivityVO);
        ActivityVO activityVO = BeanUtils.copy(activityService.getById(activityId), ActivityVO.class);
        return ResponseStatusVO.ok("取消报名成功", activityVO);
    }

    @Autowired
    public void setRanksUserService(RanksUserService ranksUserService) {
        this.ranksUserService = ranksUserService;
    }

    @Autowired
    public void setGameInfoService(GameInfoService gameInfoService) {
        this.gameInfoService = gameInfoService;
    }

    @Autowired
    public void setActivityService(ActivityService activityService) {
        this.activityService = activityService;
    }

    @Autowired
    public void setUserDetailService(UserDetailService userDetailService) {
        this.userDetailService = userDetailService;
    }

    @Autowired
    public void setActivityRanksService(ActivityRanksService activityRanksService) {
        this.activityRanksService = activityRanksService;
    }
}